<?php

namespace MoChat\App\Client\Action\Dashboard\Tag;

use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
use GuzzleHttp\Exception\GuzzleException;
use Hyperf\Contract\StdoutLoggerInterface;
use Hyperf\DbConnection\Db;
use MoChat\App\Client\Contract\ClientTagContract;
use MoChat\App\Client\Contract\ClientTagGroupContract;
use MoChat\App\WorkContact\Contract\WorkContactTagGroupContract;
use MoChat\Framework\Action\AbstractAction;
use MoChat\Framework\Constants\ErrorCode;
use MoChat\Framework\Exception\CommonException;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\Middlewares;
use Hyperf\HttpServer\Annotation\RequestMapping;
use MoChat\App\Common\Middleware\DashboardAuthMiddleware;
use MoChat\App\Rbac\Middleware\PermissionMiddleware;
use Hyperf\Di\Annotation\Inject;

use MoChat\Framework\Request\ValidateSceneTrait;
use function user;

/**
 * 客户标签创建.
 * @Controller
 */
class Create extends AbstractAction
{
    use ValidateSceneTrait;

    /**
     * @Inject
     * @var ClientTagGroupContract
     */
    protected $clientTagGroupService;

    /**
     * @Inject
     * @var ClientTagContract
     */
    protected $clientTagService;

    /**
     * @Inject
     * @var StdoutLoggerInterface
     */
    protected $logger;

    /**
     * @Middlewares({
     *     @Middleware(DashboardAuthMiddleware::class),
     * })
     *
     * @RequestMapping(path="/dashboard/clientTag/create", methods="POST")
     */
    public function handle(): array
    {
        $user = user();
        // 判断用户绑定企业信息
        if (!isset($user['corpIds']) || count($user['corpIds']) !== 1) {
            throw new CommonException(ErrorCode::INVALID_PARAMS, '未选择登录企业，不可操作');
        }
        // 接收参数
        $params['groupName'] = $this->request->input('groupName');
        $params['tags'] = $this->request->input('tags', []);
        // 验证参数
        $this->validated($params);
        // 空标签判断
        if (empty($params['groupName'])) {
            throw new CommonException(ErrorCode::INVALID_PARAMS, '分组名称不允许为空');
        }
        if (count($params['tags']) > 1) {
            foreach ($params['tags'] as $item) {
                if (empty($item['name'])) {
                    throw new CommonException(ErrorCode::INVALID_PARAMS, '标签名不允许为空');
                }
            }
        }
        // 处理参数
        $data = $this->handleParam($user, $params);
        Db::beginTransaction();
        try {
            $count = $this->clientTagGroupService->countWorkContactTagGroup($user['corpIds'][0]);
            $data['order'] = $count;
            // 创建分组
            $groupId = $this->clientTagGroupService->createWorkContactTagGroup($data);
            // 标签名称不为空，创建标签
            if (!empty($params['tags']) && !empty($params['tags'][0]['name'])) {
                $this->createTags($groupId, $params);
            }
            Db::commit();
        } catch (\Throwable $e) {
            Db::rollBack();
            $this->logger->error(sprintf('%s [%s] %s', '引流链接创建失败', date('Y-m-d H:i:s'), $e->getMessage()));
            $this->logger->error($e->getTraceAsString());
            throw new CommonException(ErrorCode::SERVER_ERROR, $e->getMessage()); // '活动创建失败'
        }
        return [];
    }

    /**
     * 处理参数.
     * @param array $user 用户信息
     * @param array $params 接受参数
     * @return array 响应数组
     */
    private function handleParam(array $user, array $params): array
    {
        // 查询是否已存在相同分组名称
        if (!empty($this->clientTagGroupService
            ->getWorkContactTagGroupsByName($user['corpIds'][0], $params['groupName']))) {
            throw new CommonException(ErrorCode::INVALID_PARAMS, '已存在相同分组名');
        }
        // 查询标签名称重复
        $tagName = array_column($params['tags'], 'name');
        if (!empty($params['tags']) && count($params['tags']) !== count(array_unique($tagName))) {
            throw new CommonException(ErrorCode::INVALID_PARAMS, '标签名称重复');
        }
        // 基本信息
        return [
            'corp_id' => $user['corpIds'][0],
            'group_name' => $params['groupName'],
        ];
    }

    /**
     * 验证规则.
     *
     * @return array 响应数据
     */
    protected function rules(): array
    {
        return [
            'groupName' => 'required|max:30'
        ];
    }

    /**
     * 验证错误提示.
     * @return array 响应数据
     */
    protected function messages(): array
    {
        return [
            'groupName.required' => '分组名称必填',
            'groupName.max' => '分组名称长度不能超过30个字符',
        ];
    }

    /**
     * 标签处理.
     */
    private function createTags(int $groupId, array $params): array
    {
        if (empty($params['tags'])) {
            return [];
        }
        $data = [];
        $count = $this->clientTagService->countWorkContactTagByGroupId($groupId);
        foreach ($params['tags'] as $val) {
            ++$count;
            $data[] = [
                'corp_id' => user()['corpIds'][0],
                'client_tag_group_id' => $groupId,
                'name' => $val['name'],
                'order' => $val['order'] ?? $count,
                'remark' => $val['remark'] ?? '',
            ];
        }
        // 批量创建标签
        $this->clientTagService->createWorkContactTags($data);
        return [];
    }

}